Skip to content

feat(guard): audit the REQUIRED fuzz context's target list, not only the advisory one (#406) - #409

Merged
avrabe merged 1 commit into
mainfrom
feat/fuzz-smoke-audit-406
Aug 8, 2026
Merged

feat(guard): audit the REQUIRED fuzz context's target list, not only the advisory one (#406)#409
avrabe merged 1 commit into
mainfrom
feat/fuzz-smoke-audit-406

Conversation

@avrabe

@avrabe avrabe commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What

tools/check_fuzz_targets.py (added for REQ-GUARD-GATE-EVIDENCE-002 (h)) audited the wrong one of two fuzz target lists. This teaches it to audit the one that actually gates merges.

  • Advisoryfuzz-nightly.yml's matrix.include, what the tool compared. Its job name is templated (Fuzz ${{ matrix.target }}), so by check_required_contexts.py's rules it can never be a required context.
  • Requiredci.yml's fuzz-smoke job (Fuzz smoke (60s/target), in .github/required-contexts.txt), which hand-writes each harness as a cargo +nightly fuzz run <target> step. It was compared against nothing.

So the covered list was advisory and the uncovered list blocked merges. Add a [[bin]] plus a nightly matrix entry but forget the fuzz-smoke step, and the tool reported All 4 declared fuzz targets are run while the required gate fuzzed 3 of 4, green, forever (#406) — the requirement's own defect shape one level up.

How

The nightly's - target: regex can't be reused: the fuzz-smoke targets sit as the positional of a cargo … fuzz run command inside run: steps. A second extractor (smoke_targets) parses them, scoped to the fuzz-smoke: job block and skipping full-line comments so a fuzz run string in prose can't poison the scan. It drops the +toolchain token, value-taking flags with their argument (so --target <triple> is never read as a harness), and the libfuzzer args after --; a command not resolving to exactly one positional is a broken scan (exit 2), never a silently dropped leg. The declaration is now asserted against both lists; the worst exit wins.

The comment-scoping is not hypothetical: an intermediate version scanned the whole file, matched this PR's own guard-step comment (cargo … fuzz run … <target>), and turned the required Rivet validate (artifacts) context red. The clean-room pass caught it before it shipped; the fix is block scoping plus a real-tree self-test row that runs the check against the committed ci.yml and asserts exit 0, so a poisoning comment fails the self-test loudly instead of reading the gate as broken.

Oracle (executed, non-vacuous)

  • --self-test grows to 18 rows (exit 0), including the The REQUIRED 'Fuzz smoke' job's target list is compared against nothing; check_fuzz_targets audits only the advisory nightly #406 acceptance criterion — a [[bin]] absent from fuzz-smoke exits 1 — whose exit differs from the base row (0) on the same tool with a distinct input, the discrimination the advisory-only tool lacked. Mutating _one_smoke_target to a constant reds the suite (not green-regardless).
  • Live: appending a fourth [[bin]] to the real fuzz/Cargo.toml makes the fuzz-smoke check exit 1 (fuzz_new_harness … NOT run by the fuzz-smoke job); the unmodified tree exits 0.
  • rivet validate → PASS; no broken cross-refs.

Artifacts

  • REQ-GUARD-FUZZ-SMOKE-001 (implemented) and TEST-GUARD-FUZZ-SMOKE (with runnable fields.steps and satisfies/verifies links).
  • The human-scoped REQ-GUARD-GATE-EVIDENCE-002 is not touched or promoted.

Honest scope

Set equality proves declaration parity, not execution — a fuzz-smoke leg carrying continue-on-error: true or if: false still counts as "run". That is a distinct obligation (execution evidence) left to a successor; this closes the list-parity hole #406 names and no more.

Closes #406.

🤖 Generated with Claude Code


Generated by Claude Code

…visory one (#406)

REQ-GUARD-GATE-EVIDENCE-002 (h) added check_fuzz_targets.py to stop the fuzz
target list drifting from its fuzz/Cargo.toml [[bin]] declaration. It audited
the wrong one of two lists.

`fuzz-nightly.yml`'s matrix (what the tool compared) is ADVISORY — its job name
is templated, so it can never be a required context. `ci.yml`'s fuzz-smoke job,
which hand-writes each harness as a `cargo fuzz run <target>` step, IS the
required context (`Fuzz smoke (60s/target)`) and was compared against nothing.
Add a [[bin]] plus a nightly matrix entry but forget the fuzz-smoke step and the
tool reported `All 4 declared fuzz targets are run` while the REQUIRED gate
fuzzed 3 of 4, green, forever.

Extending the nightly `- target:` regex to ci.yml does not work — the targets
sit as the positional of a `cargo fuzz run` command inside `run:` steps. A
second extractor (smoke_targets) parses them, scoped to the fuzz-smoke: job
block and skipping full-line comments so a `fuzz run` string in prose cannot
poison the scan, dropping the +toolchain token, value flags with their argument
(so --target <triple> is not read as a harness), and libfuzzer args after `--`;
a command not resolving to exactly one positional is a broken scan (exit 2). The
declaration is now audited against BOTH lists, worst exit wins.

Self-test grows to 18 rows, including the #406 acceptance criterion (a [[bin]]
absent from fuzz-smoke exits 1), the comment-poisoning regression, and a
real-tree row asserting the committed ci.yml is clean under both audits.

REQ-GUARD-FUZZ-SMOKE-001 + TEST-GUARD-FUZZ-SMOKE (with runnable steps and
satisfies/verifies links) record it. The human-scoped REQ-GUARD-GATE-EVIDENCE-002
is left untouched. Set equality proves DECLARATION parity, not execution — a
continue-on-error/if:false leg still counts as run; that is a distinct
obligation left to a successor.

Closes #406.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Rivet verification gate

20/20 passed

count
Passed 20
Failed 0
Skipped (no steps) 0

Filter: (and (= type "feature") (or (has-tag "v093") (has-tag "v0100")))

Failed artifacts

(none)

Updated automatically by tools/post_verification_comment.py. Source of truth: artifacts/verification.yaml.

@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe
avrabe merged commit d68fed5 into main Aug 8, 2026
21 checks passed
@avrabe
avrabe deleted the feat/fuzz-smoke-audit-406 branch August 8, 2026 04:36
@avrabe avrabe mentioned this pull request Aug 8, 2026
avrabe added a commit that referenced this pull request Aug 8, 2026
Bump workspace + vscode-spar to v0.36.0; promote REQ-GUARD-FUZZ-SMOKE-001 to verified (release v0.36.0). Ships the #409 fuzz-target guardrail fix that audits the required fuzz-smoke context's target list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The REQUIRED 'Fuzz smoke' job's target list is compared against nothing; check_fuzz_targets audits only the advisory nightly

2 participants